<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Carousel结构样式</title>

  <style>
    .container {
      max-width: 800px;
      margin: 30px auto;
      border-radius: 4px;
      box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.3);
      padding: 16px;
    }

    .carousel {
      position: relative;
      height: 200px;
    }

   .carousel .panels > a{
      position: absolute;
      display: flex;
      align-items: center;
      justify-content: center;
      width: 100%;
      height: 100%;
      text-decoration: none;
      transition: all .3s;
      opacity: 0;
      z-index: 0;
    }

    .carousel .panels > a.active {
      opacity: 1;
      z-index: 1;
    }

    .carousel .panels > a:nth-child(even) {
      background-color: lightskyblue;
    }

    .carousel .panels > a:nth-child(odd) {
      background-color: rgb(28, 202, 135);
    }

    .carousel .arrow{
      position: absolute;
      z-index: 100;
      top: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      width: 32px;
      height: 32px;
      border: none;
      border-radius: 50%;
      background-color: rgba(31, 45, 61, .11);
      opacity: 0;
      transition: all .3s;
      cursor: pointer;
      outline: none;
    }

    .carousel .arrow-pre {
      left: 10px;
      transform: translateX(-10px) translateY(-50%);
      
    }
    .carousel:hover .arrow-pre {
      transform: translateX(0) translateY(-50%);
      opacity: 1;
    }


    .carousel .arrow-next {
      right: 10px;
      transform: translateX(10px) translateY(-50%);
    }

    .carousel:hover .arrow-next {
      transform: translateX(0) translateY(-50%);
      opacity: 1;
    }

    .carousel .arrow::before {
      content: '';
      display: block;
      width: 6px;
      height: 6px;
      border-left: 1px solid #fff;
      border-top: 1px solid #fff;
      transform: rotate(-45deg);
    }

    .carousel .arrow.arrow-next::before {
      transform: rotate(135deg);
    }

    .carousel .indicators {
      position: absolute;
      z-index: 100;
      left: 50%;
      bottom: 10px;
      transform: translateX(-50%);
      list-style: none;
      margin: 0;
      padding: 0; 
    } 

    .carousel .indicators > li {
      display: inline-block;
      padding: 5px 0;
      cursor: pointer;
    }

    .carousel .indicators > li::before {
      content: '';
      display: block;
      width: 30px;
      height: 2px;
      
      background-color: #c0c4cc; 
      transition: all .3s;
    }

    .carousel .indicators > li.active::before {
      background: #fff;
      
    }

  </style>
</head>
<body>
  <div class="container">
    <h2>Carousel</h2>
    <div class="carousel">
      <div class="panels">
        <a class="active" href="#0">0</a>
        <a href="#1">1</a>
        <a href="#2">2</a>
        <a href="#3">3</a>
      </div>
      <div class="arrows">
        <button class="arrow arrow-pre"></button>
        <button class="arrow arrow-next"></button>
      </div>
      <ul class="indicators">
        <li class="active"></li>
        <li></li>
        <li></li>
        <li></li>
      </ul>
    </div>
  </div>

  <script>
    const $ = s => document.querySelector(s)
    const $$ = ss => document.querySelectorAll(ss)

    const $pre = $('.arrow-pre')
    const $next = $('.arrow-next')
    const $$indicators = $$('.indicators > li')
    const $$panels = $$('.panels > a')
    //该方法是为了找到indicators下有active的下标
    const getIndex = () => [...$$indicators].indexOf($('.indicators .active'))
    //该方法是为了计算左右两边button按键后的下标
    const getPreIndex = () => (getIndex() - 1 + $$indicators.length) % $$indicators.length
    const getNextIndex = () => (getIndex() + 1) % $$indicators.length
    //遍历panel下的a链接，删除所有的active，给对应下标的a链接增加active
    const setPage = index => {
      $$panels.forEach($panel => $panel.classList.remove('active'))
      $$panels[index].classList.add('active')
    }
    //遍历indiactors下的li，删除所有的li，给对应下标的li增加active
    const setIndicator = index => {
      $$indicators.forEach($indicator => $indicator.classList.remove('active'))
      $$indicators[index].classList.add('active')
    }
    //上按键的onclick事件，将getPreIndex计算后的下标赋值给setPage和setIndicator方法
    $pre.onclick = function() {
      let index = getPreIndex()
      setPage(index)
      setIndicator(index)
    }
    //下按键的onclick事件，将getPreIndex计算后的下标赋值给setPage和setIndicator方法
    $next.onclick = function() {
      let index = getNextIndex()
      setPage(index)
      setIndicator(index)
    }
    //遍历indicators，给遍历后的indicator增加onclick事件，参数为所点击的li
    //利用数组的方法获取所点击的下标，然后将该下标赋值给setPage和setIndicator方法
    $$indicators.forEach($indicator => $indicator.onclick = function(e) {
      let index = [...$$indicators].indexOf(e.target)
      setIndicator(index)
      setPage(index)
    })

  </script>
</body>
</html>